<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>微信年度聊天报告</title>
    <!-- 引入外部字体，提升设计感 -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;700&display=swap" rel="stylesheet">
    
    <link rel="stylesheet" href="https://memotrace.cn/static/css/fullpage.min.css" />
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@latest/dist/echarts.min.js"></script>
    <script type="text/javascript" src="https://assets.pyecharts.org/assets/v5/echarts-wordcloud.min.js"></script>
    <script type="text/javascript" src="https://assets.pyecharts.org/assets/v5/maps/china.js"></script>
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
    <script type="text/javascript" src="https://memotrace.cn/static/js/fullpage.min.js"></script>
    <script type="text/javascript" src="https://davidshimjs.github.io/qrcodejs/qrcode.min.js"></script>
    <style>
        /* --- 全局与基础样式 --- */
        :root {
            --primary-text-color: #f0f8ff; /* 主要文字颜色 (爱丽丝蓝) */
            --highlight-color: #ffde7d; /* 亮眼数字颜色 (柔和的黄色) */
            --card-bg-color: rgba(255, 255, 255, 0.1); /* 卡片背景色 */
            --card-border-color: rgba(255, 255, 255, 0.2); /* 卡片边框色 */
            --button-bg-color: rgba(255, 255, 255, 0.2); /* 按钮背景色 */
            --button-hover-bg-color: rgba(255, 255, 255, 0.3); /* 按钮悬停背景色 */
        }

        * {
            box-sizing: border-box;
        }

        body {
            /* 采用更现代、清新的动态渐变背景 */
            background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
            background-size: 400% 400%;
            animation: gradientBG 15s ease infinite;
            margin: 0;
            color: var(--primary-text-color);
            font-family: 'Noto Sans SC', sans-serif; /* 使用引入的字体 */
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
        }

        @keyframes gradientBG {
            0% { background-position: 0% 50%; }
            50% { background-position: 100% 50%; }
            100% { background-position: 0% 50%; }
        }

        .section, .slide {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            text-align: center;
            padding: 20px;
            /* 为文字添加细微阴影，增强在动态背景下的可读性 */
            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
        }

        /* --- 特效：雪花 --- */
        #snow {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
            z-index: 1000;
        }

        .snowflake {
            position: absolute;
            background-color: rgba(255, 255, 255, 0.8);
            border-radius: 50%;
            animation: snowfall linear infinite;
        }

        @keyframes snowfall {
            from {
                transform: translateY(-10vh) translateX(0) rotate(0deg);
                opacity: 1;
            }
            to {
                transform: translateY(105vh) translateX(5vw) rotate(360deg);
                opacity: 0;
            }
        }
        
        /* --- 内容通用样式 --- */
        h1 {
            font-size: 3rem;
            font-weight: 700;
            margin-bottom: 20px;
            animation: fadeInDown 1.5s ease-out;
        }

        h2 {
            font-size: 1.5rem;
            font-weight: 400;
            color: rgba(255,255,255,0.85);
            margin-top: 2rem;
            margin-bottom: 1rem;
        }

        p {
            font-size: 1.2rem;
            font-weight: 300;
            line-height: 1.8;
            max-width: 600px; /* 限制段落宽度，优化阅读 */
        }
        
        .number {
            color: var(--highlight-color);
            font-weight: 700;
            font-size: 1.3em;
            margin: 0 5px;
        }

        /* --- 玻璃拟态卡片样式 (核心设计) --- */
        .content-card {
            background: var(--card-bg-color);
            border-radius: 16px;
            box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
            backdrop-filter: blur(8px);
            -webkit-backdrop-filter: blur(8px);
            border: 1px solid var(--card-border-color);
            padding: 2em;
            transition: all 0.3s ease;
        }

        /* --- 首页样式 --- */
        #cover {
            animation: fadeIn 3s ease-out;
        }

        #enterButton {
            cursor: pointer;
            padding: 12px 28px;
            background: var(--button-bg-color);
            color: var(--primary-text-color);
            border: 1px solid var(--card-border-color);
            border-radius: 50px; /* 圆角按钮 */
            font-size: 1.1em;
            font-weight: 400;
            margin-top: 30px;
            transition: background-color 0.3s, transform 0.3s;
            backdrop-filter: blur(5px);
            -webkit-backdrop-filter: blur(5px);
        }

        #enterButton:hover {
            background-color: var(--button-hover-bg-color);
            transform: scale(1.05);
        }

        /* --- ECharts 图表容器 --- */
        .chart-container {
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .chart {
            width: 800px;
            height: 500px;
        }
        #word_cloud {
            width: 700px;
            height: 600px;
        }

        /* --- 关键词页面 --- */
        #keywords-container {
            background: rgba(0,0,0,0.15);
            padding: 1rem 3rem;
            border-radius: 10px;
            margin-bottom: 2rem;
            animation: slideIn 1.5s ease-out;
        }
        #keywords {
            font-size: 3em;
            font-weight: bold;
            color: #fff;
            margin: 0;
        }

        /* --- 好友榜单 (重构为卡片网格) --- */
        .friend-list {
            list-style: none;
            padding: 0;
            margin: 0;
            display: flex;
            flex-wrap: wrap; /* 允许换行 */
            justify-content: center;
            gap: 2em; /* 卡片间距 */
            width: 100%;
            max-width: 1200px;
        }

        .friend-list li {
            /* 应用玻璃卡片样式 */
            background: var(--card-bg-color);
            border-radius: 16px;
            box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
            backdrop-filter: blur(8px);
            -webkit-backdrop-filter: blur(8px);
            border: 1px solid var(--card-border-color);
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            width: 280px;
        }

        .friend-list li:hover {
            transform: translateY(-10px) scale(1.03);
            box-shadow: 0 8px 40px rgba(0, 0, 0, 0.2);
        }

        .friend-list a {
            text-decoration: none;
            color: var(--primary-text-color);
            display: flex;
            flex-direction: column;
            padding: 1.5em;
            height: 100%;
        }

        .contact-container {
            display: flex;
            align-items: center;
            margin-bottom: 1em;
            gap: 1em;
        }

        .avatar {
            height: 50px;
            width: 50px;
            border-radius: 50%;
            border: 2px solid rgba(255,255,255,0.5);
        }

        .nickname {
            font-size: 1.2em;
            font-weight: 700;
            text-align: left;
            flex-grow: 1; /* 占据剩余空间 */
        }
        
        .contact-stats {
            font-size: 1em;
            line-height: 1.6;
            text-align: left;
        }

        /* --- 动画 --- */
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }

        @keyframes fadeInDown {
            from {
                opacity: 0;
                transform: translateY(-20px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }
        
        @keyframes slideIn {
            from {
                opacity: 0;
                transform: translateX(-50px);
            }
            to {
                opacity: 1;
                transform: translateX(0);
            }
        }

        /* --- 响应式设计 --- */
        @media screen and (max-width: 768px) {
            h1 { font-size: 2.2rem; }
            h2 { font-size: 1.3rem; }
            p { font-size: 1rem; }
            .chart {
                width: 90vw;
                height: 400px;
            }
            #word_cloud {
                width: 90vw;
                height: 400px;
            }
            .friend-list {
                flex-direction: column; /* 小屏幕下垂直排列 */
                align-items: center;
            }
            .friend-list li {
                width: 80vw;
                max-width: 320px;
            }
            .content-card {
                padding: 1.5em;
            }
        }
    </style>
</head>
<body>
    <div id="snow"></div>

    <div id="fullpage">
      <div class="section">
          <div id="cover">
              <h1>年度聊天报告</h1>
              <p>时光荏苒，记忆永存。数据为你揭示，那些不易察觉的温暖瞬间。</p>
              <button id="enterButton" onclick="navigateToNextPage()">开启我的报告</button>
          </div>
      </div>
      
      <div class="section">
        <h1>2025年 · 总览</h1>
        <p>
            你与<span class="number">{{contact_num}}</span>位朋友留下了足迹<br>
            发送了<span class="number">{{send_msg_num}}</span>条消息，收到了<span class="number">{{receive_msg_num}}</span>条回复<br>
            你们的故事，共计<span class="number">{{total_text_num}}</span>字
        </p>
        <p>其中，男生<span class="number">{{man_contact_num}}</span>位，女生<span class="number">{{woman_contact_num}}</span>位</p>
        
        <div class="slide" data-anchor="slide1">
            <h2>朋友们来自五湖四海</h2>
            <div class="content-card chart-container">
                <div id="contact_region_map" class="chart"></div>
            </div>
        </div>
        <div class="slide" data-anchor="slide2">
            <h2>沟通的N种方式</h2>
            <div class="content-card chart-container">
                <div id="types-chart" class="chart"></div>
            </div>
        </div>
        <div class="slide" data-anchor="slide3">
            <h2>言语的博弈</h2>
            <div class="content-card chart-container">
                <div id="sender-chart" class="chart"></div>
            </div>
        </div>
      </div>

      <div class="section">
          <h1>年度关键词</h1>
          <div id="keywords-container">
            <div id="keywords">“{{keyword}}”</div>
          </div>
          <p>这个词，你一共提起了 <span class="number">{{keyword_max_num}}</span> 次</p>
          <div id="word_cloud"></div>
      </div>

      <div class="section">
          <h1>年度挚友</h1>
          <h2>与你聊得最火热的他们</h2>
          <ul class="friend-list">
              {% for contact,msg_num,text_length in contact_topN:%}
                  <li>
                      <a href="/charts/{{contact.wxid}}" target="_blank">
                          <div class="contact-container">
                              <img class="avatar" src="{{contact.smallHeadImgUrl}}" alt="avatar">
                              <p class="nickname">{{contact.remark}}</p>
                          </div>
                          <div class="contact-stats">
                              <span class="number">{{msg_num}}</span> 条消息<br>
                              <span class="number">{{text_length}}</span> 字箴言
                          </div>
                      </a>
                  </li>
              {% endfor %}
          </ul>
      </div>

      <!-- ===== 新增的结尾页 ===== -->
      <div class="section">
          <div class="content-card" style="max-width: 800px; animation: fadeIn 2s ease-out;">
              <h1 style="font-size: 2.5rem; margin-bottom: 1.5rem;">时光的结语</h1>
              <p style="font-size: 1.1rem; line-height: 2;">
                  数据可以记录每一次交流的频率，<br>
                  却无法衡量字里行间的真情与温度。<br>
                  每一个表情，每一次分享，每一次深夜长谈，<br>
                  都构成了你独一无二的年度记忆。
              </p>
              <p style="font-size: 1.3rem; font-weight: 400; color: var(--highlight-color); margin-top: 2rem;">
                  报告在此结束，但你们的故事，未完待续...
              </p>
          </div>
      </div>
      <!-- ===== 结尾页结束 ===== -->

  </div>

<script>
    // 动态生成雪花
    document.addEventListener('DOMContentLoaded', function () {
        const snowContainer = document.getElementById('snow');
        const snowflakeCount = 50; // 雪花数量
        for (let i = 0; i < snowflakeCount; i++) {
            const snowflake = document.createElement('div');
            snowflake.className = 'snowflake';
            
            const size = Math.random() * 4 + 1; // 尺寸 1px - 5px
            const left = Math.random() * 100; // 水平位置 0% - 100%
            const duration = Math.random() * 10 + 10; // 动画时长 10s - 20s
            const delay = Math.random() * 10 * -1; // 延迟，让雪花错开出现

            snowflake.style.width = `${size}px`;
            snowflake.style.height = `${size}px`;
            snowflake.style.left = `${left}vw`;
            snowflake.style.animationDuration = `${duration}s`;
            snowflake.style.animationDelay = `${delay}s`;

            if (Math.random() > 0.7) {
                snowflake.style.filter = `blur(1px)`;
            }

            snowContainer.appendChild(snowflake);
        }
    });

    // fullpage.js 初始化
    $(document).ready(function() {
      $('#fullpage').fullpage({
        navigation: true,
        navigationPosition: 'right',
        scrollingSpeed: 1000,
      });
    });

    // 导航到下一页
    function navigateToNextPage(){
        fullpage_api.moveSectionDown();
    }
</script>
<script>
    // --- ECharts 图表初始化 (已修复错误) ---
    $(document).ready(function() {
        
        // --- 好友地域分布图 ---
        var chart_region_elem = document.getElementById('contact_region_map');
        if (chart_region_elem) {
            var chart_region = echarts.init(chart_region_elem);
            var data_region = {{contact_region_map|safe}};
            // 安全地修改样式
            data_region.backgroundColor = 'transparent';
            if (data_region.title) data_region.title.textStyle = {...data_region.title.textStyle, color: '#fff'};
            if (data_region.visualMap) data_region.visualMap.textStyle = {...data_region.visualMap.textStyle, color: '#fff'};
            chart_region.setOption(data_region);
        }
        
        // --- 消息类型饼图 ---
        var chart_types_elem = document.getElementById('types-chart');
        if (chart_types_elem) {
            var chart_types = echarts.init(chart_types_elem);
            var data_types = {{chart_data_types|safe}};
            data_types.backgroundColor = 'transparent';
            if (data_types.title) data_types.title.textStyle = {...data_types.title.textStyle, color: '#fff'};
            if (data_types.legend) data_types.legend.textStyle = {...data_types.legend.textStyle, color: 'rgba(255,255,255,0.9)'};
            if (data_types.series) data_types.series.forEach(s => s.label.color = 'rgba(255,255,255,0.9)');
            chart_types.setOption(data_types);
        }

        // --- 发送/接收对比图 ---
        var chart_sender_elem = document.getElementById('sender-chart');
        if (chart_sender_elem) {
            var chart_sender = echarts.init(chart_sender_elem);
            var data_sender = {{chart_data_sender|safe}};
            data_sender.backgroundColor = 'transparent';
            if (data_sender.title) data_sender.title.textStyle = {...data_sender.title.textStyle, color: '#fff'};
            if (data_sender.legend) data_sender.legend.textStyle = {...data_sender.legend.textStyle, color: 'rgba(255,255,255,0.9)'};
            if (data_sender.xAxis && data_sender.xAxis[0]) data_sender.xAxis[0].axisLabel.color = 'rgba(255,255,255,0.9)';
            if (data_sender.yAxis && data_sender.yAxis[0]) data_sender.yAxis[0].axisLabel.color = 'rgba(255,255,255,0.9)';
            chart_sender.setOption(data_sender);
        }

        // --- 词云图 ---
        var chart_wordcloud_elem = document.getElementById('word_cloud');
        if (chart_wordcloud_elem) {
            var chart_wordcloud = echarts.init(chart_wordcloud_elem);
            var data_wordcloud = {{chart_data_wordcloud|safe}};
            data_wordcloud.backgroundColor = 'transparent';
            if(data_wordcloud.series && data_wordcloud.series[0]){
                data_wordcloud.series[0].textStyle = {
                    ...data_wordcloud.series[0].textStyle,
                    color: function() {
                        var colors = ['#f0f8ff', '#ffde7d', '#87cefa', '#98fb98', '#dda0dd', '#fff'];
                        return colors[Math.floor(Math.random() * colors.length)];
                    }
                };
                 const screenWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
                data_wordcloud.series[0].sizeRange = screenWidth < 768 ? [12, 50] : [20, 100];
            }
            chart_wordcloud.setOption(data_wordcloud);
        }
        
        // 监听窗口大小变化，重绘所有图表
        window.addEventListener('resize', function() {
            if(chart_region) chart_region.resize();
            if(chart_types) chart_types.resize();
            if(chart_sender) chart_sender.resize();
            if(chart_wordcloud) chart_wordcloud.resize();
        });
    });
</script>
</body>
</html>